using System;
using System.Collections;
using System.Threading.Tasks;
using UnityEngine;
using UnityEngine.Events;
using MyFramework.Event;
using MyFramework.Mono;
using MyFramework.Resource;
using MyFramework.Singleton;
using UnityEngine.SceneManagement;

namespace MyFramework.Scene
{
    /// <summary>
    /// 提供场景切换的公共接口
    /// </summary>
    public class SceneManager : Singleton<SceneManager>
    {
        private readonly LoadSceneConfig _config =
            ResourcesManager.GetInstance().Load<LoadSceneConfig>("config/SceneConfig");

        /// <summary>
        /// 切换场景（同步）
        /// </summary>
        /// <param name="sceneName"></param>
        public void LoadScene(string sceneName)
        {
            UnityEngine.SceneManagement.SceneManager.LoadScene(sceneName);
        }

        /// <summary>
        /// 切换场景（异步）
        /// </summary>
        /// <param name="sceneName"></param>
        /// <param name="fun"></param>
        public async void LoadSceneAsync(string sceneName, UnityAction fun)
        {
            try
            {
                await PreLoadProcess();

                //使用公共Mono模块开启协程
                MonoManager.GetInstance().StartCoroutine(ReallyLoadSceneAsync(sceneName, fun));
            }
            catch (Exception e)
            {
                Debug.LogError(e.Message);
            }
        }

        /// <summary>
        /// 协程异步加载场景
        /// </summary>
        /// <param name="sceneName"></param>
        /// <param name="fun"></param>
        /// <returns></returns>
        private static IEnumerator ReallyLoadSceneAsync(string sceneName, UnityAction fun)
        {
            //场景异步加载
            AsyncOperation asyncOperation = UnityEngine.SceneManagement.SceneManager.LoadSceneAsync(sceneName);

            while (asyncOperation is not { isDone: true })
            {
                //利用事件中心模块向外分发加载进度
                EventCenterManager.GetInstance().EventTrigger("", asyncOperation!.progress);

                //更新进度
                yield return asyncOperation.progress;
            }

            //加载场景完成后才会去执行委托函数
            fun?.Invoke();
        }

        /// <summary>
        /// 预加载处理
        /// </summary>
        private static async Task PreLoadProcess()
        {
            // 垃圾回收
            GC.Collect();

            // 清理资源缓存
            Resources.UnloadUnusedAssets();

            // 等待一帧，确保清理完成
            await Task.Yield();
        }

        /// <summary>
        /// 后加载处理
        /// </summary>
        private async Task PostLoadProcess(string sceneName)
        {
            // 预加载下一个可能的场景
            if (_config.preloadNextScene)
            {
                var nextScene = GetNextSceneName(sceneName);
                if (!string.IsNullOrEmpty(nextScene))
                {
                    _ = PreloadSceneAsync(nextScene);
                }
            }

            await Task.Yield();
        }
        
        /// <summary>
        /// 预加载场景到内存
        /// </summary>
        public async Task PreloadSceneAsync(string sceneName)
        {
            // if (SceneCache.GetInstance().IsSceneCached(sceneName))
            //     return;
            //
            // var preloadOperation = UnityEngine.SceneManagement.SceneManager.LoadSceneAsync(sceneName, LoadSceneMode.Additive);
            // preloadOperation.allowSceneActivation = false;
            //
            // while (!preloadOperation.isDone && preloadOperation.progress < 0.9f)
            // {
            //     await Task.Yield();
            // }
            //
            // SceneCache.GetInstance().CacheScene(sceneName, preloadOperation);
        }

        /// <summary>
        /// 获取下一个场景名称（可根据项目需求自定义）
        /// </summary>
        private static string GetNextSceneName(string currentScene)
        {
            // 这里可以根据项目的场景跳转逻辑来实现 比如使用ScriptableObject配置好做动态读取
            // 示例：简单的场景序列
            return currentScene switch
            {
                "MainMenu" => "GameScene",
                "GameScene" => "ResultScene",
                _ => null
            };
        }
    }
}